package multi;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;

public class MultiThreadDownFile {
	public static void main(String[] args) {
		try {
			String filePath = "http://dl_dir.qq.com/qqfile/qd/QQ2012Beta3_QQProtect2.8.exe";
			int threadNum = 5;
			new MultiThreadDown().down(filePath, threadNum);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

class MultiThreadDown extends Thread {

	private int threadId;
	private int block;
	private URL url;
	private File file;

	public MultiThreadDown() {
	}

	public MultiThreadDown(int threadId, int block, URL url, File file) {
		super();
		this.threadId = threadId;
		this.block = block;
		this.url = url;
		this.file = file;
	}

	public void down(String path, int threadNum) throws Exception {
		URL url = new URL(path);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(5000);
		conn.setRequestMethod("GET");
		try {
			if (conn.getResponseCode() == 200) {
				int fileLength = conn.getContentLength();// Get the length of
															// NetFile
				System.out.println("网络文件大小：" + fileLength);
				File file = new File(getFilename(path));
				RandomAccessFile raf = new RandomAccessFile(file, "rwd");
				raf.setLength(fileLength);
				raf.close();
				// 计算每条线程的下载量
				int block = fileLength % threadNum == 0 ? fileLength
						/ threadNum : fileLength / threadNum + 1;
				for (int threadId = 0; threadId < threadNum; threadId++) {
					new MultiThreadDown(threadId, block, url, file).start();
					System.out.println("线程" + threadId + "开始");
				}
			} else {
				System.out.println("Connection failed.");
			}
		} catch (Exception e) {
			System.out.println("连接失败.");
			e.printStackTrace();
		}
	}

	private String getFilename(String path) {
		return path.substring(path.lastIndexOf("/") + 1);
	}

	@Override
	public void run() {
		super.run();
		int start = threadId * block;// 计算线程下载的网络文件的文件位置
		int end = (threadId + 1) * block - 1;// 线程的结束位置
		try {
			RandomAccessFile raf = new RandomAccessFile(file, "rwd");
			raf.seek(start);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
			if (conn.getResponseCode() == 206) {
				InputStream is = conn.getInputStream();
				byte[] buf = new byte[1024];
				int len = 0;
				while ((len = is.read(buf)) != -1) {
					raf.write(buf, 0, len);
				}
				raf.close();
				is.close();
			}
			System.out.println("第" + threadId + "线程下载完毕");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}